package com.idroc.message;

import org.apache.mina.common.ByteBuffer;

/**
 * 抽象消息
 * @author 赤脚詹(yuyoo4j@163.com)
 * @date Aug 17, 2009 4:09:15 PM
 * @memo:保证encode或者decode只会被执行一次
 */
public abstract class AbstractMessage implements Message {

	protected MessageType type = null;
	
	/**
	 * 是否解码过标记
	 */
	protected boolean decoded = false;
	/**
	 * 是否编码过标记
	 */
	protected boolean encoded = false;
	
	protected AbstractMessage() {
		
		type = MessageType.get(this.getClass());
		if (null == type) {
			// 注册消息类型
			type = MessageType.registry(this.getClass());
		}
	}

	/**
	 * 解码消息
	 */
	public void decode(ByteBuffer ib) {

		if (!decoded) {
			decoded = true;
			int msgId = ib.getInt();
			MessageType type = MessageType.get(msgId);
			if (null == type) {
				throw new RuntimeException("不能解析消息类型异常:未找到消息类型");
			}
			this.type = type;
			decodeMessage(ib);
		} else {
			throw new IllegalStateException();
		}	
	}

	/**
	 * 编码消息
	 */
	public void encode(ByteBuffer ob) {

		if (!encoded) {
			encoded = true; 
			ob.putInt(type.getMsgId());
			encodeMessage(ob);
			if (ob.position() <= 4) {
				throw new RuntimeException("格式化消息内容无效异常:未正常写入数据");
			} 
		} else {
			throw new IllegalStateException();			
		}
	}

	/**
	 * 是否解码过
	 */
	public boolean isDecoded() {
		return decoded;
	}

	/**
	 * 是否编码过
	 */
	public boolean isEncoded() {
		return encoded;
	}
	
	/**
	 * 获取消息类型
	 * @return -- 消息类型
	 */
	public MessageType getMsgType() {
		return type;
	}
	
	/**
	 * 解码消息
	 * @param inBuffer -- 包含消息信息的ByteBuffer
	 */
	protected abstract void decodeMessage(ByteBuffer in);
	
	/**
	 * 编码消息
	 * @return -- 包含消息信息的ByteBuffer
	 */
	protected abstract void encodeMessage(ByteBuffer out); 
	
}
